package com.coolw.test.sftp.monitor;

import com.jcraft.jsch.SftpProgressMonitor;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.text.DecimalFormat;
import java.util.Timer;
import java.util.TimerTask;

/**
 * 按固定时间频率监控sftp传输
 *
 * @author coolw
 * @date 2023/11/17 10:54
 */
@Slf4j
public class TimeSftpProgressMonitor1 extends TimerTask implements SftpProgressMonitor {

    /**
     * 时间间隔，默认为5秒
     */
    private final long progressInterval = 5 * 1000;
    /**
     * 记录传输是否结束
     */
    private boolean isEnd = false;
    /**
     * 记录已传输的数据总大小
     */
    private long transfered;
    /**
     * 记录文件总大小
     */
    private long fileSize;
    /**
     * 定时器对象
     */
    private Timer timer;
    /**
     * 记录是否已启动timer记时器
     */
    private boolean isScheduled = false;

    @Override
    public void run() {
        if (isEnd) {
            log.info("文件传输已结束,取消定时器");
            stop();
            return;
        }

        long transfered = getTransfered();
        if (transfered != fileSize) {
            double d = ((double) transfered * 100) / (double) fileSize;
            DecimalFormat df = new DecimalFormat("#.##");
            log.info("当前传输进度为 {}%, 已传输 {} bytes", df.format(d), transfered);
        } else {
            log.info("当前传输进度为 100%, 已传输 {} bytes", transfered);
            setEnd(true);
        }
    }

    public void start() {
        if (timer == null) {
            timer = new Timer();
        }
        timer.schedule(this, 1000, progressInterval);
        isScheduled = true;
        log.info("传输监控启动");
    }

    public void stop() {
        if (timer != null) {
            timer.cancel();
            timer.purge();
            timer = null;
            isScheduled = false;
        }
        log.info("传输监控停止");
    }

    @Override
    public void init(int op, String src, String dest, long max) {
        log.info("Transfer start...............");

        File file = new File(src);
        this.fileSize = file.length();
        log.info("本次传输文件总大小 {} bytes", fileSize);
    }

    @Override
    public boolean count(long count) {
        if (isEnd) {
            return false;
        }
        if (!isScheduled) {
            start();
        }
        add(count);
        return true;
    }

    @Override
    public void end() {
        setEnd(true);
        log.info("Transfer end...............");
    }

    private synchronized void add(long count) {
        transfered += count;
    }

    private synchronized long getTransfered() {
        return this.transfered;
    }

    public synchronized void setTransfered(long transfered) {
        this.transfered = transfered;
    }

    private synchronized void setEnd(boolean isEnd) {
        this.isEnd = isEnd;
    }

    private synchronized boolean isEnd() {
        return isEnd;
    }
}
